#include "driver.h"
#include "CancelSafeQueue.h"
extern LIST_ENTRY g_TransportIrpQueue;
extern IO_CSQ g_CancelSafeQueue;

NTSTATUS US_StartDeviceCompletionRoutine(IN PDEVICE_OBJECT fido, IN PIRP Irp, IN PUSBFILTER_DEVICE_EXTENSION pdx)
{							// US_StartDeviceCompletionRoutine
	if (Irp->PendingReturned)
		IoMarkIrpPending(Irp);


	if (pdx->AttachedToDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
		fido->Characteristics |= FILE_REMOVABLE_MEDIA;

	IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
	return STATUS_SUCCESS;
}

NTSTATUS US_CompletionRoutine(IN PDEVICE_OBJECT fido, IN PIRP pIrp, IN PVOID context)
{
	
	US_PassPacketToUserMode(pIrp, TRUE);
	return STATUS_SUCCESS;
}

BOOLEAN US_PassPacketToUserMode(PIRP pIrp, BOOLEAN isCompleted)
{
	PIRP pIrpOut;
	PIO_STACK_LOCATION IrpStackOut;
	char* pOutDataBuffer;

	pIrpOut = IoCsqRemoveNextIrp(&g_CancelSafeQueue, NULL);

	if(pIrpOut)
	{
		IrpStackOut = IoGetCurrentIrpStackLocation(pIrpOut);

		if(IrpStackOut)
		{
			pOutDataBuffer = (PCHAR)MmGetSystemAddressForMdlSafe(pIrpOut->MdlAddress, 
																	NormalPagePriority);
			//here pOutBuffer fills
			if(pOutDataBuffer)
			{         
				RtlCopyMemory(pOutDataBuffer, "something", 10);
			}
			pIrpOut->IoStatus.Status	= STATUS_SUCCESS;

			IoCompleteRequest(pIrpOut, IO_NO_INCREMENT);
			return TRUE;
		}
	}
	return FALSE;
}

NTSTATUS US_CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
{							// US_CompleteRequest
	Irp->IoStatus.Status = status;
	Irp->IoStatus.Information = info;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
}

VOID US_RemoveDevice(IN PDEVICE_OBJECT fido)
{							// US_RemoveDevice
	PUSBFILTER_DEVICE_EXTENSION pdx = (PUSBFILTER_DEVICE_EXTENSION) fido->DeviceExtension;
	
	NTSTATUS status;
	
	if (pdx->AttachedToDeviceObject)
		IoDetachDevice(pdx->AttachedToDeviceObject);

	IoDeleteDevice(fido);
}							// US_RemoveDevice

/*ULONG GetDeviceTypeToUse(PDEVICE_OBJECT pdo)
{							// GetDeviceTypeToUse
	PDEVICE_OBJECT ldo = IoGetAttachedDeviceReference(pdo);
	if (!ldo)
		return FILE_DEVICE_UNKNOWN;
	unsigned long devtype = ldo->DeviceType;;
	ObDereferenceObject(ldo);
	return devtype;;
}*/	